package cn.ibizlab.modeling.groovy;

import groovy.transform.CompileStatic
import net.ibizsys.central.dataentity.action.DEActionRuntimeBase
import net.ibizsys.central.util.IEntityDTO
import org.eclipse.jgit.api.*
import org.eclipse.jgit.lib.Ref
import org.eclipse.jgit.transport.UsernamePasswordCredentialsProvider

import java.nio.charset.StandardCharsets
import java.nio.file.*
import net.ibizsys.central.dataentity.IDataEntityRuntime

import java.util.stream.Stream

@CompileStatic
class GitSyncDEActionRuntime extends DEActionRuntimeBase{

    public GitSyncDEActionRuntime() {
    }

    @Override
    protected Object onExecute(IEntityDTO iEntityDTO) throws Throwable {
        String sourceRepoUrl = iEntityDTO.getString("sourcegitpath","" ) // 替换为你的源仓库URL
        String sourceBranch = iEntityDTO.getString("sourcebranch","master") // 替换为你的源分支名称
        String targetRepoUrl = iEntityDTO.getString("targetgitpath",iEntityDTO.getString("gitpath",""))  // 替换为你的目标仓库URL
        String targetBranch = iEntityDTO.getString("targetbranch",iEntityDTO.getString("gitbranch",""))  // 替换为目标分支名称
        String gitUsername = iEntityDTO.getString("gitusername","")  // 替换为你的Git用户名
        String gitPassword = iEntityDTO.getString("gittoken",iEntityDTO.getString("gitpassword","")) // 替换为你的Git密码或访问令牌
        boolean sourcePublic = iEntityDTO.getBoolean("sourcepublic",true)

        if((!targetRepoUrl||!gitPassword)&&iEntityDTO.get("psdevcentersvnid")!=null) {
            IEntityDTO repo = null
            IEntityDTO svn = null
            IEntityDTO gitUser = null
            try {
                IDataEntityRuntime entityDataEntityRuntime = this.getSystemRuntime().getDataEntityRuntime("PSDEVCENTERSVN")
                repo = entityDataEntityRuntime.get(iEntityDTO.get("psdevcentersvnid"),true)
            }
            catch (Exception ex) {

            }
            if(repo) {
                if(!targetRepoUrl)
                    targetRepoUrl = repo.getString("gitpath", "")
                if (!targetBranch)
                    targetBranch = repo.getString("gitbranch", "master")

                String svnServerId = repo.getString("pssvnserverid","")
                String gitUserId = repo.getString("psgituserid","")

                if(targetRepoUrl) {
                    try {
                        if (!gitPassword && svnServerId) {
                            svn = this.getSystemRuntime().getDataEntityRuntime("PSSVNSERVER").get(svnServerId, true)
                            if (svn) {
                                gitPassword = svn.getString("gittoken", svn.getString("gitpassword", ""))
                                if (!gitUsername)
                                    gitUsername = svn.getString("gitusername", "ibizdev")
                            }
                        } else if (!gitPassword && gitUserId) {
                            gitUser = this.getSystemRuntime().getDataEntityRuntime("PSGITUSER").get(gitUserId, true)
                            if (gitUser) {
                                gitPassword = gitUser.getString("password", "")
                                if (!gitUsername)
                                    gitUsername = gitUser.getString("username", "ibizdev")
                            }
                        }
                    }
                    catch (Exception ex) {

                    }
                }



            }
        }


        if(!sourceRepoUrl || !targetRepoUrl || !gitPassword)
            throw new Exception("git仓库参数缺失");



        String sourceGitUsername = iEntityDTO.getString("sourcegitusername", gitUsername) // 替换为你的源仓库URL
        String sourceGitPassword = iEntityDTO.getString("sourcegitpassword", gitPassword) // 替换为你的源分支名称

        if (sourceRepoUrl.indexOf("/oauth2:")>0)
            sourceGitPassword = parseCredentialsFromUrl(sourceRepoUrl)

        if (targetRepoUrl&&targetRepoUrl.indexOf("/oauth2:")>0) {
            gitPassword = parseCredentialsFromUrl(targetRepoUrl)
            if (!gitUsername)
                gitUsername = "ibizdev"
        }


        syncRepos(sourceRepoUrl, sourceBranch, sourceGitUsername, sourceGitPassword, targetRepoUrl, targetBranch, gitUsername, gitPassword, iEntityDTO.getString("systemname",null))
        return iEntityDTO
    }

    public void syncRepos(String sourceRepoUrl, String sourceBranch, String sourceGitUsername, String sourceGitPassword,String targetRepoUrl, String targetBranch, String gitUsername, String gitPassword, String systemName) {
        Path sourceRepoDir = Files.createTempDirectory("source-repo")
        Path targetRepoDir = Files.createTempDirectory("target-repo")

        Git sourceGit


        Git targetGit
        try {
            // 克隆源仓库

            if (sourceRepoUrl == targetRepoUrl) {
                sourceGit = Git.cloneRepository()
                        .setURI(sourceRepoUrl)
                        .setDirectory(sourceRepoDir.toFile())
                        .setCredentialsProvider(new UsernamePasswordCredentialsProvider(gitUsername, gitPassword))
                        .setBranch(sourceBranch)
                        .call()



                // 同一个仓库

                List<Ref> remoteBranches = sourceGit.branchList()
                        .setListMode(ListBranchCommand.ListMode.REMOTE)
                        .call()

                boolean remoteBranchExists = remoteBranches.any { ref ->
                    ref.getName().endsWith("/${targetBranch}")
                }

                sourceGit.checkout()
                        .setName(sourceBranch)
                        .call()

                if (!remoteBranchExists) {
                    targetGit = sourceGit
                    // 目标分支不存在，基于源分支创建新分支
                    targetGit.checkout()
                            .setCreateBranch(true)
                            .setName(targetBranch)
                            .setStartPoint("origin/" + sourceBranch)
                            .call()
                    targetGit.push()
                            .setRemote(targetRepoUrl)
                            .setCredentialsProvider(new UsernamePasswordCredentialsProvider(gitUsername, gitPassword))
                            .add(targetBranch)
                            .call()

                    println "操作成功完成！"
                    return
                }

            }
            else {
                if(sourceGitPassword) {
                    try {
                        sourceGit = Git.cloneRepository()
                                .setURI(sourceRepoUrl)
                                .setDirectory(sourceRepoDir.toFile())
                                .setCredentialsProvider(new UsernamePasswordCredentialsProvider(sourceGitUsername, sourceGitPassword))
                                .setBranch(sourceBranch)
                                .call()
                    }catch (Exception ex) {
                        try{
                            sourceGit = Git.cloneRepository()
                                    .setURI(sourceRepoUrl)
                                    .setDirectory(sourceRepoDir.toFile())
                                    .setBranch(sourceBranch)
                                    .call()

                        }catch (Exception ex2) {
                            if(gitPassword && !gitPassword.equals(sourceGitPassword))
                                sourceGit = Git.cloneRepository()
                                        .setURI(sourceRepoUrl)
                                        .setDirectory(sourceRepoDir.toFile())
                                        .setCredentialsProvider(new UsernamePasswordCredentialsProvider(gitUsername, gitPassword))
                                        .setBranch(sourceBranch)
                                        .call()
                        }
                    }
                }
                else {
                    sourceGit = Git.cloneRepository()
                            .setURI(sourceRepoUrl)
                            .setDirectory(sourceRepoDir.toFile())
                            .setBranch(sourceBranch)
                            .call()
                }
            }


            // 不同仓库
            targetGit = Git.cloneRepository()
                    .setURI(targetRepoUrl)
                    .setDirectory(targetRepoDir.toFile())
                    .setCredentialsProvider(new UsernamePasswordCredentialsProvider(gitUsername, gitPassword))
                    .setBranch(targetBranch)
                    .call()

            if((!systemName) && sourceRepoUrl.equals("https://code.ibizlab.cn/model/quickstart.git"))
                systemName = extractSystemName(targetRepoUrl)

            copyFolderRecursively(sourceRepoDir, targetRepoDir, systemName)

            targetGit.add().addFilepattern(".").call()
            targetGit.commit().setMessage("Update from script").call()


            // 推送到远程仓库
            targetGit.push()
                    .setCredentialsProvider(new UsernamePasswordCredentialsProvider(gitUsername, gitPassword))
                    .add(targetBranch)
                    .call()

            println "操作成功完成！"
        } catch (Exception e) {
            throw new Exception("Git同步内容失败:"+e,e);
        } finally {

            try {
                sourceGit?.close()
            } catch (Exception ex) {
                println "关闭Git资源时警告: ${ex.message}"
            }

            try {
                targetGit?.close()
            } catch (Exception ex) {
                println "关闭Git资源时警告: ${ex.message}"
            }
            deleteDirectoryRecursively(sourceRepoDir)
            deleteDirectoryRecursively(targetRepoDir)
        }
    }

    private static String parseCredentialsFromUrl(String gitUrl) {
        if(!gitUrl)
            return ""
        try {
            // 兼容包含多个@的情况（如密码中含@）
            URI uri = new URI(gitUrl)
            String userInfo = uri.userInfo

            if (!userInfo) return null

            // 分割用户名和密码（支持密码中含:）
            int colonIndex = userInfo.indexOf(':')
            if (colonIndex <= 0) return null

            String username = userInfo.substring(0, colonIndex)
            String password = userInfo.substring(colonIndex + 1)

            // URL 解码处理特殊字符
            username = URLDecoder.decode(username, "UTF-8")
            password = URLDecoder.decode(password, "UTF-8")

            return password
        } catch (Exception e) {
            return ""
        }
    }


    private static void copyFolderRecursively(Path source, Path target, String systemName) {
        Stream<Path> stream = null
        try  {
            stream = Files.walk(source)
            stream.forEach { path ->
                if (!path.toFile().getName().equals(".git")) {  // 排除.git目录
                    Path relative = source.relativize(path)
                    if (!relative.startsWith(".git")) {
                        Path targetPath = target.resolve(relative)
                        if (Files.isDirectory(path)) {
                            Files.createDirectories(targetPath)
                        } else {
                            if (systemName && (path.toFile().getName().equals("PSSYSAPP.json") || path.toFile().getName().equals("PSSYSSFPUB.json"))) {
                                // 如果是目标文件，读取并修改其内容
                                String content = new String(Files.readAllBytes(path), StandardCharsets.UTF_8)
                                content = content.replace("quickstart", systemName)
                                Files.write(targetPath, content.getBytes(StandardCharsets.UTF_8))
                            } else {
                                // 否则直接复制文件
                                Files.copy(path, targetPath, StandardCopyOption.REPLACE_EXISTING)
                            }
                        }
                    }
                }
            }
        } catch (IOException e) {
            e.printStackTrace()
        } finally {
            if (stream != null) {
                try {
                    stream.close() // 手动关闭流
                } catch (Exception e) {
                    println "流关闭失败: ${e.message}"
                }
            }
        }
    }

    private static void deleteDirectoryRecursively(Path dir) {
        try {
            new File(dir.toString()).deleteDir()
            println "已删除临时目录: ${dir}"
        } catch (IOException e) {
            println "删除临时目录失败: ${dir}"
            e.printStackTrace()
        }
    }

    private String extractSystemName(String repoUrl) {
        // 从URL中提取最后一部分（即仓库名）
        def lastSegment = repoUrl.tokenize('/')[-1]

        // 查找_model的位置
        def modelNameIndex = lastSegment.indexOf('_model')

        if (modelNameIndex != -1) {
            // 返回_model之前的字符串
            return lastSegment[0..modelNameIndex-1]
        } else {
            return null
        }
    }

//    static void main(String[] args) {
//        // 测试参数
//        String sourceRepoUrl = "https://code.ibizlab.cn/model/quickstart.git"  // 替换为你的源仓库URL
//        String sourceBranch = "master"  // 替换为你的源分支名称
//        String targetRepoUrl = "http://op.ibizlab.cn/tf1874f3dd2ad5459003564d0d981fe01/training_model.git"  // 替换为你的目标仓库URL
//        String targetBranch = "master"  // 替换为目标分支名称
//        String gitUsername = "ibizdev"  // 替换为你的Git用户名
//        String gitPassword = "glpat-Js"  // 替换为你的Git密码或访问令牌
//
//        try {
//            // 创建GitSync实例并同步仓库
//            GitSyncDEActionRuntime gitSync = new GitSyncDEActionRuntime()
//            gitSync.syncRepos(sourceRepoUrl, sourceBranch, targetRepoUrl, targetBranch, gitUsername, gitPassword, null)
//
//            println("仓库同步成功完成！")
//        } catch (Exception e) {
//            e.printStackTrace()
//            println("仓库同步过程中发生错误：${e.message}")
//        }
//    }

}